#SingleInstance, force

SetWorkingDir %A_ScriptDir%
SetWinDelay, 0
DetectHiddenWindows, On

Main:
    Menu, Tray, NoStandard
    Menu, Tray, Add, &Reload, Reload
    Menu, Tray, Add, &Exit, Exit
    
    GloBal Theme := ReadIni("econfig.ini", "config", "theme", "light")    
    GloBal Color := ReadIni("econfig.ini", "config", "color", "Auto")
    GloBal ETPath := ReadIni("econfig.ini", "config", "everythingPath", "")

    If(Color == "Auto"){
        WinWaitActive, ahk_class CabinetWClass
        WinGetActiveStats, t, w, h, x, y
        CoordMode, Pixel, Screen
        Sleep, 500
        PixelGetColor, Color, x + 15, y + 15, Slow RGB
    }

    GloBal EwindowArr := []
    GloBal TabArr := []

    GloBal LastX, LastY, LastW, LastH

    GloBal MaxTabWidth := 160
    GloBal CurTabWidth := 160
    GloBal MinGuiWidth := 320

    TabPicPath = theme\%Theme%\tab.png
    GloBal TabPic := LoadPicture(TabPicPath)

    GloBal Locked := False

    Hotkey, IfWinActive, ahk_class CabinetWClass
    Hotkey, MButton, MButtonEvent
    Hotkey, IfWinActive

    GUIInit()

    SetTimer, GUI_FOLLOW_PROCESS, 25
    SetTimer, GUI_TAB_ADD_PROCESS, 50
    SetTimer, GUI_TAB_REMOVE_PROCESS, 70
ReTurn

GUI_FOLLOW_PROCESS(){
    If(Locked){
        Return
    }
    Locked := True
    EHwnd := WinActive("ahk_class CabinetWClass")
    WinGetActiveStats, T, W, H, X, Y
    
    If (EHwnd != 0){
        If(WinExist("ahk_class #32768")){
            Gui, Hide
        }Else{
            EHwnd := Format("{:d}", EHwnd)
            EwindowArr[EHwnd].SetTitle(T)
            If(X > 0 && Y > 0 && TabArr.MaxIndex() > 0){
                Gui, Show, % "x" X + 109 "." "y" Y + 1 "." "w" (TabArr.MaxIndex() * CurTabWidth) "." "h30 NA"
                LastW := W
                LastH := H
                LastX := X
                LastY := Y
            }
            If(StrLen(ETPath) > 0){
                ControlGetFocus, FocusItem
                If(FocusItem == "Windows.UI.Core.CoreWindow1"){
                    For window In ComObjCreate("Shell.Application").Windows{
                        If (window.hwnd==EHwnd){
                            Folder := % Trim(window.Document.Folder.Self.Path)"\"
                            If((SubStr(Folder, 1, 3) == "::{")){
                                Folder := "*"
                            }
                            Run, % ETPath " -s " Folder
                            Break
                        }
                    }
                }
            }
        }
    }Else{
        Gui, Hide
    }
    Locked := False
}

GUI_TAB_ADD_PROCESS(){
    If(Locked){
        Return
    }
    Locked := True
    WinGet, EHwndList, List, ahk_class CabinetWClass
    If(EHwndList > TabArr.MaxIndex()){
        LastEW := False
        InitArr := []
        Loop, %EHwndList%{
            EHwnd := Format("{:d}", EHwndList%A_Index%)
            If(!EwindowArr[EHwnd]){
                InitArr.InsertAt(1, EHwnd)
            }
        }
        For index, eHwnd in InitArr{
            WinGetTitle, etitle, ahk_id %eHwnd%
            EW := new EWindow(etitle, eHwnd)                
            LastEW := EW
            EwindowArr[eHwnd] := EW
            TabArr.push(eHwnd)
        }
        If(LastEW){
            LastEW.Active(True)
            For eIndex, eValue in TabArr{
                EwindowArr[eValue].Active(eValue == LastEW.hwnd)
            }
        }
    }
    Locked := False
}

GUI_TAB_REMOVE_PROCESS(){
    If(Locked){
        Return
    }
    Locked := True
    Rebuild := False
    For eIndex, eValue in TabArr{
        If(!ExistWin(eValue)){
            Rebuild := True
        }
    }
    If(Rebuild){
        EwindowArr := []
        TabArr := []
        Gui, Destroy
        GUIInit()
    }
    Locked := False
}


GUIInit(){
    Gui, Margin, 0, 0
    Gui, +AlwaysOnTop +ToolWindow -Caption
    Gui, Color, %Color%
    Gui, Font, c000000 s9 w500, Microsoft YaHei
}

MButtonEvent(){
    MouseGetPos, , , , hCtrl, 1
    If(SubStr(hCtrl, 1, 6) == "Static"){
        CloseTab()
    }Else{
        Send {RButton}
        WinWait, ahk_class #32768
        Send {E}
    }
}

CloseTab() {
    MouseGetPos, , , , hCtrl, 2
    If(hCtrl){
        GuiControlGet, name, Name, %hCtrl%
        If(name){
            FirstChar := SubStr(name, 1, 1)
            If(FirstChar == "P" || FirstChar == "T"){
                eHwnd := SubStr(name, 2)
                newEHwnd := 0
                For eIndex, eValue in TabArr{
                    If(eValue != eHwnd){
                        newEHwnd := eValue
                    }
                }
                If(newEHwnd != 0){
                    EwindowArr[newEHwnd].Active(True)
                }
                WinClose, ahk_id %eHwnd%
            }
        }
    }
}

ChangeTab(){
    activeHwnd := SubStr(A_GuiControl, 2)
    EwindowArr[activeHwnd].Active(True)
    For eHwnd, EW in EwindowArr{
        EW.Active(eHwnd == activeHwnd)
    }
}

ExistWin(ehwnd){
    ehwnd := % "ahk_id " Format("{:#x}", ehwnd)
    Return WinExist(ehwnd)
}

ReadIni(file, section, name, defaultValue){
    IniRead, obj, %file%, %section%, %name%, %defaultValue%
    If(StrLen(obj) == 0 || obj == "ERROR"){
        obj := defaultValue
    }
    Return obj
}

Reload(){
    if(A_IsCompiled){
        Run "%A_ScriptFullPath%"
    }else{
        Run "%A_AhkPath%" "%A_ScriptFullPath%"
    }
}

Exit(){
    ExitApp
}


class EWindow{
    __New(ETitle, EHwnd)
    {
        this.title := ETitle
        this.hwnd := EHwnd
        this.Init()
        Return this
    }

    Init(){
        global
        title := this.title
        ehwnd := this.hwnd
        Gui, Add, Picture, vP%ehwnd% gChangeTab y0, % "HBITMAP:*" TabPic
        GuiControlGet, PicPos, Pos, P%ehwnd%
        TextPosX := PicPosX + 8
        CurTextWidth := CurTabWidth - 10
        Gui, Add, Text, vT%ehwnd% x%TextPosX% y6 w%CurTextWidth%, %title%
    }

    Active(active){
        ehwnd := this.hwnd
        If(active == True){
            WinGetPos, cX, cY, cWidth, cHeight, ahk_id %ehwnd%
            If(StrLen(LastX) > 0 && StrLen(LastY) > 0 && StrLen(LastW) > 0 && StrLen(LastH) > 0 ){
                If(StrLen(cX) > 0 && StrLen(cY) > 0 && StrLen(cWidth) > 0 && StrLen(cHeight) > 0){
                    If(cX != LastX || cY != LastY || cWidth != LastW || cHeight != LastH){
                        WinMove, ahk_id %ehwnd%, , %LastX%, %LastY%, %LastW%, %LastH%
                    }
                }
            }
            WinShow, ahk_id %ehwnd%
            WinActivate, ahk_id %ehwnd%
            GuiControl, Move, P%eHwnd%, y0 w%CurTabWidth%
        }Else{
            WinHide, ahk_id %ehwnd%
            GuiControl, Move, P%ehwnd%, y3 w%CurTabWidth%
        }
    }

    SetTitle(ETitle){
        If(ETitle != this.title){
            EHwnd := this.hwnd
            this.title := ETitle
            GuiControl, Text, T%EHwnd%, %ETitle%
        }
    }
}